<template>
  <div class="outer">
    <div class="dialog">
      <div class="two">
        <div class="img">
          <img src="@/assets/img/ai助手.png" alt="" style="width: 100%" />
        </div>
        <div class="content">
          <div class="title" id="0" style="display: flex; flex-direction: row">
            {{ welcome }}
          </div>
          <div class="icon">
            <div class="copy">
              <svg-icon icon-name="copy"></svg-icon>
              <div style="margin-left: 5px" @click="copyDomText()">复制</div>
            </div>
          </div>
        </div>
      </div>
      <div v-for="(item, index) in contentArr" :key="index">
        <!-- 用户输出 -->
        <div class="one" v-show="item.inputtext !== ''">
          <span class="title">{{ item.inputtext }}</span>
        </div>

        <!-- ai输出 -->
        <div class="two">
          <div class="img">
            <img src="@/assets/img/ai助手.png" alt="" style="width: 100%" />
          </div>
          <div class="content">
            <!-- <VueMarkdown
              class="title"
              style="display: flex; flex-direction: row"
              :source="item.restext"
              :sanitize="false" 
            >
            </VueMarkdown> -->

            <div
              class="title"
              style="display: flex; flex-direction: row; padding: 5px"
              v-html="markdown.render(item.restext)"
            ></div>
            <div class="icon">
              <div class="copy">
                <svg-icon icon-name="copy"></svg-icon>
                <div style="margin-left: 5px" @click="handleCopy(item.restext)">
                  复制
                </div>
              </div>
              <div class="retry">
                <svg-icon icon-name="retry"></svg-icon>
                <div style="margin-left: 5px" @click="doItAgain">再试一次</div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="input">
      <textarea
        placeholder="请输入内容"
        id="inputcon"
        class="prompt"
        v-model="prompt"
        @keyup.enter="send()"
      ></textarea>
      <div class="bottom">
        <div class="right">
          <!-- <div class="send" id="sending" @click="send">
            <svg-icon icon-name="unsend" class="sendno"></svg-icon>
            <svg-icon icon-name="send" class="truesend"></svg-icon>
          </div> -->
          <el-button
            type="primary"
            :disabled="isContent"
            :loading="isSend"
            :icon="Right"
            style="
              padding: 5px 8px;
              border-radius: 50%;
              background-color: #f8daa8;
              border: #f8daa8;
            "
            @click="send()"
          />
        </div>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ElMessage } from "element-plus";
import { onMounted, onUnmounted, reactive, ref, watch } from "vue";
import { Right } from "@element-plus/icons-vue";
import { chat } from "@/api/ai.js";
import clipBoard from "vue-clipboard3";
import VueMarkdown from "vue-markdown";
import { bus } from "@/utils/mitt";
import { useRoute, useRouter } from "vue-router";
import Cookies from "js-cookie";
import MarkdownIt from "markdown-it";
const markdown = new MarkdownIt();
let { toClipboard } = clipBoard(); // 一键复制

onMounted(() => {
  if (positionId.value !== "" && positionId.value !== undefined) {
    aMockInterview();
  }
});
// onUnmounted(() => {
//     bus.off("aMockInterview");
//   });
const route = useRoute();

const positionId = ref(route.query.id); // 获取查询参数 id

//欢迎语句
const welcome = ref(
  "你好！请问有什么可以帮助你的？如果你有任何问题或者需要建议，请随时告诉我。"
);
//用户输出内容
const prompt = ref("");
const isContent = ref(true);
const isSend = ref(false);

watch(prompt, (newValue, oldValue) => {
  if (prompt.value) {
    isContent.value = false;
  } else {
    isContent.value = true;
  }
});

//复制功能
const copyDomText = () => {
  // const dom = document.getElementById('0') as HTMLInputElement;
  const titleElement = document.getElementById("0");
  if (titleElement) {
    const text = titleElement.innerText;
    navigator.clipboard
      .writeText(text)
      .then(() => {
        ElMessage({
          message: "复制成功",
          type: "success",
        });
      })
      .catch((err) => {
        ElMessage({
          message: "复制失败",
          type: "error",
        });
      });
  }
};

//内容数组
const contentArr = ref<Array<{ inputtext: string; restext: string }>>([]);

// watch(contentArr.value, (newValue, oldValue) => {
//   if (prompt.value) {
//     isContent.value = false;
//   } else {
//     isContent.value = true;
//   }
// });
// 响应内容
const responseText = ref("");

// 一键复制
const handleCopy = async (str: string) => {
  try {
    await toClipboard(str);
    ElMessage({
      message: "复制成功",
      type: "success",
    });
  } catch (e) {
    ElMessage({
      message: "复制失败",
      type: "error",
    });
  }
};
//刷新功能
const doItAgain = () => {
  prompt.value = contentArr.value[contentArr.value.length - 1].inputtext;
  contentArr.value.pop();
  isSend.value = false;
  send();
};

const send = async () => {
  if (!prompt.value) return;
  isSend.value = true;

  // 创建新条目并推入数组
  const newItem = ref({
    inputtext: prompt.value,
    restext: "",
  });
  contentArr.value.push(newItem.value);

  try {
    const token = Cookies.get("token");
    const response = ref();
    // 使用 fetch 发送 POST 请求并接收流式响应
    response.value = await fetch(
      "http://81.71.154.186:8088/api/ali/chat/stream",
      {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          token: `${token}`, // 添加 token
        },
        body: JSON.stringify({ prompt: prompt.value }),
      }
    );

    prompt.value = "";

    if (!response.value.ok) {
      throw new Error(`HTTP error! status: ${response.value.status}`);
    }

    // 获取可读流和阅读器
    const reader = response.value.body.getReader();
    const decoder = new TextDecoder();
    const lastItem = contentArr.value[contentArr.value.length - 1];
    // 消息队列
    const messageQueue = [];

    // 逐字打印函数
    const printMessage = async (message) => {
      for (let i = 0; i < message.length; i++) {
        lastItem.restext += message[i];
        await new Promise((resolve) => setTimeout(resolve, 10)); // 每个字符间隔 10ms
      }
    };

    while (true) {
      const { done, value } = await reader.read();
      if (done) {
        isSend.value = false;
        break;
      }

      // 解码数据块
      const chunk = decoder.decode(value, { stream: true });

      // 按行分割数据块
      const lines = chunk.split("\n");
      console.log(lines);

      lines.forEach((line) => {
        // 去除多余的空白字符
        const trimmedLine = line.trim();

        // 如果是有效的数据行，则处理
        if (trimmedLine.startsWith("data:")) {
          const data = trimmedLine.substring(5).trim(); // 去掉 "data:" 前缀并去除多余空白
          if (data) {
            // 忽略空行
            messageQueue.push(data);
          }
        } else if (!trimmedLine.startsWith("event:")) {
          const data = trimmedLine.substring(0).trim(); // 去掉 "data:" 前缀并去除多余空白
          if (data) {
            // 忽略空行
            messageQueue.push(data);
          }
        }
      });

      // 如果队列中有消息，开始逐字打印
      while (messageQueue.length > 0) {
        const message = messageQueue.shift(); // 从队列中取出消息
        await printMessage(message); // 逐字打印消息
      }
    }
  } catch (error) {
    isSend.value = false;
    console.error("请求失败:", error);
    alert("请求失败，请检查网络或重试！");
  }
};

const aMockInterview = async () => {
  isSend.value = true;

  // 创建新条目并推入数组
  const newItem = ref({
    inputtext: prompt.value || "",
    restext: "",
  });
  contentArr.value.push(newItem.value);
  // 修改后的代码：使用 reactive 创建响应式对象

  try {
    // 使用 fetch 发送 POST 请求并接收流式响应
    const token = Cookies.get("token");
    const PositionId = positionId.value;
    const response = await fetch(
      `http://81.71.154.186:8088/api/jobPostings/interview/${PositionId}`,
      {
        method: "GET",
        headers: {
          "Content-Type": "application/json",
          token: `${token}`, // 添加 token
        },
        // body: JSON.stringify({ prompt: prompt.value }),
      }
    );

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    // 获取可读流和阅读器
    const reader = response.body.getReader();
    const decoder = new TextDecoder();
    const lastItem = contentArr.value[contentArr.value.length - 1];
    // 消息队列
    const messageQueue = [];

    // 逐字打印函数
    const printMessage = async (message) => {
      for (let i = 0; i < message.length; i++) {
        // 直接修改响应式对象的属性
        lastItem.restext += message[i];
        await new Promise((resolve) => setTimeout(resolve, 10));
      }
    };

    while (true) {
      const { done, value } = await reader.read();
      if (done) {
        isSend.value = false;
        break;
      }

      // 解码数据块
      const chunk = decoder.decode(value, { stream: true });

      // 按行分割数据块
      const lines = chunk.split("\n");
      console.log(lines);

      lines.forEach((line) => {
        // 去除多余的空白字符
        const trimmedLine = line.trim();

        // 如果是有效的数据行，则处理
        if (trimmedLine.startsWith("data:")) {
          const data = trimmedLine.substring(5).trim(); // 去掉 "data:" 前缀并去除多余空白
          if (data) {
            // 忽略空行
            messageQueue.push(data);
          }
        } else if (!trimmedLine.startsWith("event:")) {
          const data = trimmedLine.substring(0).trim(); // 去掉 "data:" 前缀并去除多余空白
          if (data) {
            // 忽略空行
            messageQueue.push(data);
          }
        }
      });

      // 如果队列中有消息，开始逐字打印
      while (messageQueue.length > 0) {
        const message = messageQueue.shift(); // 从队列中取出消息
        await printMessage(message); // 逐字打印消息
      }
    }
  } catch (error) {
    isSend.value = false;
    console.error("请求失败:", error);
    alert("请求失败，请检查网络或重试！");
  }
};
</script>

<style lang="scss" scoped>
* {
  margin: 0;
  padding: 0;
  /* overflow-y: hidden; */
}

.outer {
  display: flex;
  flex-direction: column;
  overflow-y: hidden;
  /* 隐藏外层滚动条 */
  overflow-x: hidden;
  min-height: 86vh;
}

/* 对话框 */
.dialog {
  overflow-y: auto;
  max-height: 64vh;
  border-radius: 20px;
}

/* 左对话 */
.one {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 10px;
  margin-top: 10px;
  width: 100%;
  white-space: pre-wrap;
}

.one span {
  max-width: 50%;
  display: inline-block;
  border: 7px solid transparent; /* 修改了 border-block 为 border */
  background-color: #f0f0f0;
  text-align: right;
  // height: 40px;
  line-height: 40px;
  padding: 4px 20px;
  border-radius: 20px;
  word-wrap: break-word; /* 添加此属性实现自动换行 */
  white-space: normal; /* 确保内容可以正常换行 */
}

/* 回答 */
.two {
  display: flex;
  justify-content: flex-start;
  margin-top: 10px;
}

.two .img {
  display: flex;
  flex-wrap: wrap;
  align-content: center;
  justify-content: center;
  width: 50px;
  height: 50px;
  border-radius: 50%;
  margin-right: 3px;
}

.two .content {
  background-color: #f0f0f0;
  border-radius: 20px;
  width: 700px;
}

.two .title {
  border-block: 7px;
  /* 保留原有的边框样式 */
  text-align: left;
  /* 将文本对齐方式改为左对齐，更符合对话框的常见布局 */
  padding: 4px 20px 0 20px;
  /* 保留原有的内边距 */
  word-wrap: break-word;
  /* 自动换行 */
  line-height: 1.5;
  /* 设置行距为1.5 */
  white-space: normal;
  /* 确保内容正常换行，避免溢出 */
}

.icon {
  display: flex;
  margin: 10px;
  margin-top: 0;
  cursor: pointer;
}

.copy,
.retry,
.share {
  display: flex;
  align-items: center;
  margin-left: 5px;
  padding: 2px;
  color: rgb(94 103 114);
}

.copy:hover,
.retry:hover,
.share:hover {
  display: flex;
  align-items: center;
  padding: 2px;
  margin-left: 5px;
  background-color: rgb(94 103 114 / 35%);
  color: black;
  border-radius: 5px;
}

/* 所有图标 */
svg-icon {
  margin-right: 5px;
}

/* 输入框 */
.input {
  background-color: #fff;
  position: relative;
  position: fixed;
  bottom: 0px;
  width: 95%;
  height: 80px;
  border-radius: 20px;
  padding-left: 10px;
  padding-top: 10px;
  margin-bottom: 20px;
}

/* 输入框文字部分 */
.prompt {
  width: 100%;
  height: 100%;
  border: none;
  background-color: transparent;
  font-size: 18px;
  color: #000;
  outline: none;
  border-radius: 20px;
  padding: 10px;
  
}

/* 输入框底部部分 */
.input .bottom {
  position: fixed;
  bottom: 20px;
  display: flex;
  margin: 5px;
  width: 90%;
  justify-content: space-between;
  flex-direction: row-reverse;
  margin-bottom: 30px;
}

/* .input .bottom .left {
    display: flex;
    height: 30px;
    line-height: 30px;
    cursor: pointer;
} */

.input .bottom .right {
  display: flex;
  height: 30px;
  line-height: 30px;
  cursor: pointer;
  transform: scale(2);
}

/* 底部右边链接图标和发送图标 */
.line,
.send {
  margin-right: 10px;
  cursor: pointer;
}

.send {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 20px;
  height: 20px;
  border-radius: 10px;
  background-color: #ccc;
  position: absolute;
  right: 0;
  bottom: 0;
  padding: 5px;
}

.truesend {
  display: none;
}

.send:hover .sendno {
  display: none;
}

.send:hover .truesend {
  display: inline-block;
}

//滚动条样式 美化
::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}

::-webkit-scrollbar-track {
  width: 6px;
  background: rgba(#101f1c, 0.1);
  -webkit-border-radius: 2em;
  -moz-border-radius: 2em;
  border-radius: 2em;
}

::-webkit-scrollbar-thumb {
  background-color: rgba(144, 147, 153, 0.5);
  background-clip: padding-box;
  min-height: 28px;
  -webkit-border-radius: 2em;
  -moz-border-radius: 2em;
  border-radius: 2em;
  transition: background-color 0.3s;
  cursor: pointer;
}

::-webkit-scrollbar-thumb:hover {
  background-color: rgba(144, 147, 153, 0.3);
}
</style>
